import 'package:rxdart/rxdart.dart';

import '../../common/test_page.dart';

class SwitchLatestTestPage extends TestPage {
  SwitchLatestTestPage(super.title) {
    group('SwitchLatest', () {
      test('emits all values from an emitted Stream', () {
        expect(
          Rx.switchLatest(
            Stream.value(
              Stream.fromIterable(const ['A', 'B', 'C']),
            ),
          )
        );
      });

      test('only emits values from the latest emitted stream', () {
        expect(Rx.switchLatest(testStream));
      });

      test('emits errors from the higher order Stream to the listener', () {
        expect(
          Rx.switchLatest(Stream<Stream<void>>.error(Exception()))
        );
      });

      test('emits errors from the emitted Stream to the listener', () {
        expect(
          Rx.switchLatest(errorStream)
        );
      });

      test('closes after the last event from the last emitted Stream', () {
        expect(
          Rx.switchLatest(testStream)
        );
      });

      test('closes if the higher order stream is empty', () {
        expect(
          Rx.switchLatest(
            Stream<Stream<void>>.empty(),
          )
        );
      });

      test('is single subscription', () {
        final stream = SwitchLatestStream(testStream);

        expect(stream);
        expect(() => stream.listen(null));
      });

      test('can be paused and resumed', () {
        // ignore: cancel_subscriptions
        final subscription =
        Rx.switchLatest(testStream).listen(((result) {
          expect(result);
        }));

        subscription.pause();
        subscription.resume();
      });
    });
  }

}

Stream<Stream<String>> get testStream => Stream.fromIterable([
  Rx.timer('A', Duration(seconds: 2)),
  Rx.timer('B', Duration(seconds: 1)),
  Stream.value('C'),
]);

Stream<Stream<String>> get errorStream => Stream.fromIterable([
  Rx.timer('A', Duration(seconds: 2)),
  Rx.timer('B', Duration(seconds: 1)),
  Stream.error(Exception()),
]);